package yxy.game.pm2.module.union.boss;

import yxy.apple.util.concurrent.ThreadPoolManager;
import yxy.cherry.battle.module.Position;
import yxy.cherry.battle.module.record.FighterSide;
import yxy.cherry.battle.module.record.result.StatisticFighter;
import yxy.cherry.data.DataCenter;
import yxy.cherry.data.bean.herodata;
import yxy.cherry.data.bean.unionboss;
import yxy.cherry.data.bean.unionbossreward;
import yxy.cherry.data.string.GameString;
import yxy.game.pm2.Result;
import yxy.game.pm2.bean.Currency;
import yxy.game.pm2.bean.Format.FormatType;
import yxy.game.pm2.bean.PlayerBean;
import yxy.game.pm2.bean.module.RedisLock;
import yxy.game.pm2.bean.module.rank.RankEntry;
import yxy.game.pm2.bean.module.rank.openserviceactive.OpenServiceRushRankEnum;
import yxy.game.pm2.bean.module.rank.openserviceactive.boosrushrank.OpenServiceBoosRushRank;
import yxy.game.pm2.bean.mq.CCReason;
import yxy.game.pm2.bean.task.TaskType;
import yxy.game.pm2.message.BattleMessage;
import yxy.game.pm2.message.UnionBossMessage;
import yxy.game.pm2.message.UnionBossMessage.UnionBossRankResponse.Builder;
import yxy.game.pm2.module.CurrencyHandle;
import yxy.game.pm2.module.active.openservicerush.OpenServiceRushRecord;
import yxy.game.pm2.module.battle.*;
import yxy.game.pm2.module.battle.FighterModule.InitHpResidual;
import yxy.game.pm2.module.mail.MailHandle;
import yxy.game.pm2.module.mail.MailTypeEnum;
import yxy.game.pm2.module.player.PlayerHandle;
import yxy.game.pm2.module.task.TaskHandle;
import yxy.game.pm2.module.union.UnionBean;
import yxy.game.pm2.module.union.player.UnionPlayer;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.Set;

public class UnionBossHandle {

    private String code() {
        return BattleType.UNIONBOSS.name();
    }

    /**
     * 处理战斗
     */
    public Result battleResponseExecute(UnionPlayer unionPlayer, UnionBean union, UnionBossMessage.UnionBossChanllengeExecuteResponse.Builder response)
            throws Exception {
        String playerCode = unionPlayer.getPlayerCode();
        UnionBoss boss = UnionBoss.get(union);
        unionboss data = boss.data();

        BattleHandle battleHandle = new BattleHandle();

        BattleModule battleModule = BattleModule.create(playerCode);
        battleModule.setType(BattleType.UNIONBOSS);
        battleModule.setCode(code());

        // 玩家的team
        TeamModule teamA = battleHandle.teamPlayer(playerCode, FormatType.普通);
        battleModule.setTeamA(teamA);

        // 玩家的team
        TeamModule teamB = teamBoss(boss);
        battleModule.setTeamB(teamB);

        BattleMessage.BattleExecuteResponse res = new BattleHandle().battleResponseExecute(battleModule //
                , data.getRound(), false, null);

        // 计算伤害
        long damage = 0;
        for (StatisticFighter fighter : battleModule.getStatistics()) {
            if (fighter.getPos().getSide().equals(FighterSide.RIGHT)) {
                damage += fighter.getHut();
            }
        }

        Collection<Currency> rewards = handleDamage(union, unionPlayer, boss, damage);

        // 封装消息
        response.setBattleResp(res);// 录像
        response.setBattleResult(battleModule.getBattleResult().getNumber());// 战果
        response.setDamage(damage);
        response.addAllRewards(new CurrencyHandle().packItems(rewards));

        TaskHandle.handle(playerCode, TaskType.统计型_联盟_BOSS_挑战_次数, 1);

        return Result.Success;
    }

    /**
     * 处理扫荡
     */
    public Result bossSweep(UnionPlayer unionPlayer, UnionBean union, UnionBossMessage.UnionBossSweepResponse.Builder response) {
        UnionBoss boss = UnionBoss.get(union);
        UnionPlayerBoss playerBoss = unionPlayer.getBoss();

        if (playerBoss.getBossId() != boss.getDataId() || playerBoss.getDamage() <= 0) {
            return Result.ParamError;// 玩家没有对boss有上一次的伤害记录
        }

        // 计算伤害
        long damage = playerBoss.damage(boss.getDataId());
        Collection<Currency> rewards = handleDamage(union, unionPlayer, boss, damage);

        response.setDamage(damage);
        response.addAllRewards(new CurrencyHandle().packItems(rewards));

        TaskHandle.handle(unionPlayer.getPlayerCode(), TaskType.统计型_联盟_BOSS_挑战_次数, 1);

        return Result.Success;
    }

    /**
     * 处理伤害
     */
    private Collection<Currency> handleDamage(UnionBean union, UnionPlayer unionPlayer, UnionBoss boss, long damage) {
        String playerCode = unionPlayer.getPlayerCode();
        unionboss data = boss.data();
        UnionPlayerBoss playerBoss = unionPlayer.getBoss();

        // 伤害排名记录
        RankUnionBoss rankBoss = new RankUnionBoss(boss, boss.getDataId());
        rankBoss.addAndSet(playerCode, damage);
        // 个人玩家记录
        playerBoss.setBossId(boss.getDataId());
        playerBoss.setDamage(damage);
        playerBoss.setTimes(playerBoss.getTimes() + 1);
        playerBoss.setTotalDamageForDay(playerBoss.getTotalDamageForDay() + damage);
        unionPlayer.set();

        if (damage < boss.getResidual()) {
            boss.setResidual(boss.getResidual() - damage);
            boss.set();
        } else {
            // 排名奖励
            rankReward(union, rankBoss, data, unionPlayer);

            // 联盟BOSS击杀奖励
            if (!playerBoss.getBossReward().contains(data.getCode())) {
                // 判断是否已经获得过这个boss的奖励
                Currency killreward = Currency.create(data.getRewardtype(), data.getRewardid(), data.getRewardnum());
                ArrayList<Currency> rewards = new ArrayList<>();
                rewards.add(killreward);
                // 发邮件
                String title = GameString.联盟boss伤害击杀奖励_title(data.getName()).getText();
                String content = GameString.联盟boss伤害击杀奖励_msg(data.getName()).getText();
                new MailHandle().sendMail(playerCode, MailTypeEnum.Mail, title, content, CCReason.联盟BOSS, rewards);

                playerBoss.getBossReward().add(data.getCode());
                unionPlayer.set();
            }

            // 换boss
            boss.nextboss();

            TaskHandle.handle(playerCode, TaskType.统计型_联盟_BOSS_击杀_次数, 1);
            Runnable runnable = () -> {
                String code = union.getCode();
                boolean isRepeat = OpenServiceBoosRushRank
                        .updateBoosRanking(playerCode, 1, code, OpenServiceRushRankEnum.开服冲榜_齐心协力.getType());
                //记录任务信息
                if (isRepeat) {
                    OpenServiceRushRecord.recordFirstCompleteBoosTask(playerCode, boss.getDataId() - 1);
                }
            };
            ThreadPoolManager.getInstance().execute(runnable);
        }

        // 联盟BOSS挑战奖励
        Collection<Currency> rewards = Currency.create(data.getGhosttype(), data.getGhostid(), data.getGhostnum());
        new CurrencyHandle().addCurrency(playerCode, CCReason.联盟BOSS, rewards);
        return rewards;
    }

    private void rankReward(UnionBean union, RankUnionBoss rankBoss, unionboss data, UnionPlayer killer) {
        Set<String> members = union.members();
        Map<String, unionbossreward> all = DataCenter.getAllData(unionbossreward.class);
        for (unionbossreward rankdata : all.values()) {
            Collection<RankEntry> rankEntries = rankBoss.range(rankdata.getRankingmin(), rankdata.getRankingmax());
            Collection<Currency> rewards = Currency.create(rankdata.getRewardtype(), rankdata.getRewardid(), rankdata.getRewardnum());
            int rank = rankdata.getRankingmin();
            for (RankEntry entry : rankEntries) {
                String playerCode = entry.getKey();
                if (!members.contains(playerCode)) {
                    continue;
                }
                // 发邮件
                if (killer.getPlayerCode().equals(playerCode) && !killer.getBoss().getBossReward().contains(data.getCode())) {
                    rankReward(playerCode, data, rank, rewards);
                    continue;
                }
                RedisLock lock = UnionPlayer.lock(playerCode);
                try {
                    if (lock.tryLock()) {
                        UnionPlayer unionPlayer = UnionPlayer.get(playerCode);
                        UnionPlayerBoss playerBoss = unionPlayer.getBoss();
                        if (!playerBoss.getBossReward().contains(data.getCode())) {
                            rankReward(playerCode, data, rank, rewards);
                            playerBoss.getBossReward().add(data.getCode());
                            unionPlayer.set();
                        }
                    }
                } catch (InterruptedException e) {
                } finally {
                    lock.unlock();
                }
                rank++;
            }
        }
    }

    private void rankReward(String playerCode, unionboss data, int rank, Collection<Currency> rewards) {
        String title = GameString.联盟boss伤害排名奖励_title().getText();
        String content = GameString.联盟boss伤害排名奖励_msg(data.getName(), rank).getText();
        new MailHandle().sendMail(playerCode, MailTypeEnum.Mail, title, content, CCReason.联盟BOSS, rewards);
    }

    public TeamModule teamBoss(UnionBoss boss) {
        TeamModule team = new TeamModule();
        unionboss _bossdata = DataCenter.getData(boss.getDataId(), unionboss.class);
        // 武将
        Position position = Position.FM;
        int heroid = _bossdata.getFront();
        int level = _bossdata.getLevel();
        int anger = 0;

        FighterModule fighterModule = FighterModule.create(heroid, level, 0, 0, anger, new InitHpResidual(boss.getHp(), boss.getResidual()));
        fighterModule.getProperty().setLife(boss.getHp());
        fighterModule.getProperty().setLifeAdd(0);
        team.addfighter(position, fighterModule);

        // 信息
        herodata _herodata = DataCenter.getData(heroid, herodata.class);
        team.setName(_herodata.getName());
        team.setHead(_bossdata.getHeadid());
        team.setPower(team.power());

        return team;
    }

    public Result bossInfo(String playerCode, int bossId, UnionBean union, UnionPlayer unionPlayer, UnionBossMessage.UnionBossResponse.Builder response) {
        UnionBoss unionBoss = UnionBoss.get(union);
        if (bossId > unionBoss.getDataId()) {
            return Result.ParamError;
        }
        int _bossId = bossId <= 0 ? unionBoss.getDataId() : bossId;
        response.setBossId(_bossId);
        if (_bossId == unionBoss.getDataId()) {
            response.setHp(unionBoss.getHp());
            response.setResidual(unionBoss.getResidual());
            response.setDamage(unionPlayer.getBoss().damage(_bossId));
        }
        response.setTimes(unionPlayer.getBoss().times());
        response.setBuytimes(unionPlayer.getBoss().buytimes());

        // 前三名
        RankUnionBoss rankBoss = new RankUnionBoss(unionBoss, _bossId);
        Collection<RankEntry> entrys = rankBoss.top(3);
        int rank = 0;
        for (RankEntry entry : entrys) {
            String key = entry.getKey();
            long value = entry.getValue();
            PlayerBean player = PlayerBean.get(key);
            UnionBossMessage.TopUnionBoss.Builder builder = UnionBossMessage.TopUnionBoss.newBuilder();
            builder.setRank(++rank);
            builder.setName(player.getName());
            builder.setDamage(value);
            response.addTop(builder);
        }
        // 玩家的名次
        rank = rankBoss.rank(playerCode);
        response.setRank(rank);
        response.setTotalDamage(unionPlayer.getBoss().getTotalDamageForDay());
        return Result.Success;
    }

    public Result bossRank(String playerCode, int bossId, UnionBean union, UnionPlayer unionPlayer, Builder response) {
        UnionBoss unionBoss = UnionBoss.get(union);
        if (bossId > unionBoss.getDataId()) {
            return Result.ParamError;
        }
        int _bossId = bossId <= 0 ? unionBoss.getDataId() : bossId;

        // 排行榜
        RankUnionBoss rankBoss = new RankUnionBoss(unionBoss, _bossId);
        Collection<RankEntry> entrys = rankBoss.top(0);
        int rank = 0;
        for (RankEntry entry : entrys) {
            String key = entry.getKey();
            long value = entry.getValue();
            UnionBossMessage.RankUnionBoss.Builder builder = UnionBossMessage.RankUnionBoss.newBuilder();
            builder.setRank(++rank);
            builder.setPlayerInfo(new PlayerHandle().playerSimpleInfo(key));
            builder.setDamage(value);
            response.addRank(builder);
        }
        // 玩家的名次
        {
            int playerRank = 0;
            int value = 0;
            RankEntry entry = rankBoss.get(playerCode);
            if (entry != null) {
                playerRank = rankBoss.rank(playerCode);
                value = entry.getValue().intValue();
            }
            UnionBossMessage.RankUnionBoss.Builder builder = UnionBossMessage.RankUnionBoss.newBuilder();
            builder.setRank(playerRank);
            builder.setPlayerInfo(new PlayerHandle().playerSimpleInfo(playerCode));
            builder.setDamage(value);
            response.setMy(builder);
        }

        return Result.Success;
    }

}
